import * as BABYLON from "babylonjs";

export class Scene3D {
    private _canvas: HTMLCanvasElement;
    private _engine: BABYLON.Engine;
    private _scene: BABYLON.Scene;
    private _camera: BABYLON.ArcRotateCamera;
    private _light: BABYLON.Light;
    constructor(canvasId: string) {
        this._canvas = document.getElementById(canvasId) as HTMLCanvasElement;
        this._engine = new BABYLON.Engine(this._canvas, true);
        this._scene = {} as BABYLON.Scene;
        this._camera = {} as BABYLON.ArcRotateCamera;
        this._light = {} as BABYLON.Light;
    }

    createScene(): void {
        this._scene = new BABYLON.Scene(this._engine);
        // 1. 设置纯色背景
        // this._scene.clearColor = new BABYLON.Color4(0.5, 0.5, 0.7, 1);
        // this._scene.ambientColor = new BABYLON.Color3(0.3, 0.3, 0.3);

        // 2. 天空盒
        let skybox = BABYLON.Mesh.CreateBox('skybox', 100.0, this._scene);
        let skyboxMaterial = new BABYLON.StandardMaterial('sbMaterial', this._scene);
        skyboxMaterial.backFaceCulling = false; // 背面显示
        skyboxMaterial.disableLighting = true;

        // skyboxMaterial.reflectionTexture = new BABYLON.Texture('textures/skybox1/Ely1_nx.jpg', this._scene);
        // skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
        let envTexture = skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture('textures/SpecularHDR.dds', this._scene);
        this._scene.createDefaultSkybox(envTexture, true, 1000);

        skybox.material = skyboxMaterial;
        skybox.infiniteDistance = true; //天空盒跟随相机移动

        // 3 雾
        this._scene.fogMode = BABYLON.Scene.FOGMODE_EXP; // 雾密度遵循指数函数。 _EXP2 - 与上述相同但更快。 LINEAR - 雾密度遵循线性函数。
        this._scene.fogDensity = 0.01; // 密度 EXP/EXP2模式
        // this._scene.fogStart = 20.0; // Linear模式
        // this._scene.fogEnd = 60.0;  // Linear模式
        this._scene.fogColor = new BABYLON.Color3(0.9, 0.9, 0.85);

        this._camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 1, 2, 20, new BABYLON.Vector3(0, 0, 0), this._scene);
        this._camera.attachControl(this._canvas, true);
        this._light = new BABYLON.HemisphericLight('mylight', new BABYLON.Vector3(0, 1, 0), this._scene);
    }

    createShape() {
        let box = BABYLON.Mesh.CreateBox("box", 1, this._scene);
        let boxmat = new BABYLON.StandardMaterial('boxMat', this._scene);
        boxmat.backFaceCulling = false;
        boxmat.diffuseColor = new BABYLON.Color3(0.5, 0.5, 0.7);
        box.material = boxmat;
    }

    async animationExecution(animatable) {
        console.log('begin ... ');
        await animatable.waitAsync();
        console.log('after ...')
    }

    doRender(): void {
        // Run the render loop.
        this._engine.runRenderLoop(() => {
            this._scene.render();
        });

        // The canvas/window resize event handler.
        window.addEventListener('resize', () => {
            this._engine.resize();
        });
    }
}